/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * HDRResponseFunctionCalculatorFrame.java
 *
 * Created on 27.11.2008, 08:37:45
 */
package hdr_plugin;

import hdr_plugin.Exceptions.TypeNotSupportedException;
import hdr_plugin.response.ResponseFunctionCalculator;
import hdr_plugin.helper.ArrayTools;
import hdr_plugin.response.ResponseFunction;
import ij.IJ;
import ij.ImagePlus;
import ij.gui.PlotWindow;
import ij.io.SaveDialog;
import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Alexander Heidrich <alexander.heidrich@hki-jena.de>
 */
public class HDRResponseFunctionCalculatorFrame extends java.awt.Frame {

    private ResponseFunctionCalculator calculator;
    private ResponseFunction out;

    /** Creates new form HDRResponseFunctionCalculatorFrame */
    public HDRResponseFunctionCalculatorFrame(ResponseFunctionCalculator calculator) {
        initComponents();
        this.calculator = calculator;
        this.txtNoOfPixels.setText(String.valueOf(calculator.getResponseFunctionCalculatorSettings().getNoOfPixelsN()));
        this.txtNoOfChannels.setText(String.valueOf(calculator.getResponseFunctionCalculatorSettings().getNoOfChannels()));
        this.txtNoOfImages.setText(String.valueOf(calculator.getResponseFunctionCalculatorSettings().getNoOfImages()));
        this.txtExpTimes.setText(ArrayTools.arrayToString(calculator.getResponseFunctionCalculatorSettings().getExpTimes()));
        this.lblAlgorithm_.setText(calculator.getAlgorithm());
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        lblLogo = new javax.swing.JLabel();
        pnlContent = new java.awt.Panel();
        lblNoOfPixels = new java.awt.Label();
        lblNoOfImages = new java.awt.Label();
        lblNoOfChannels = new java.awt.Label();
        lblExpTimes = new java.awt.Label();
        lblAlgorithm = new java.awt.Label();
        lblAlgorithm_ = new java.awt.Label();
        lblLambda = new java.awt.Label();
        txtNoOfPixels = new java.awt.TextField();
        txtNoOfImages = new java.awt.TextField();
        txtNoOfChannels = new java.awt.TextField();
        txtExpTimes = new java.awt.TextField();
        txtLambda = new java.awt.TextField();
        pnlButtons = new java.awt.Panel();
        btnCalc = new java.awt.Button();
        btnSaveBin = new java.awt.Button();
        btnSaveTxt = new java.awt.Button();
        btnShow = new java.awt.Button();
        btnCancel = new java.awt.Button();
        btnHelp = new java.awt.Button();

        setBackground(new java.awt.Color(255, 255, 255));
        setResizable(false);
        setTitle("Calculate Response Function");
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });
        setLayout(new java.awt.GridBagLayout());

        lblLogo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/hdr_plugin/resources/log.jpg"))); // NOI18N
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0);
        add(lblLogo, gridBagConstraints);

        pnlContent.setLayout(new java.awt.GridBagLayout());

        lblNoOfPixels.setText("Number of Pixels (N):");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(lblNoOfPixels, gridBagConstraints);

        lblNoOfImages.setText("Number of Images (P):");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(lblNoOfImages, gridBagConstraints);

        lblNoOfChannels.setText("Number of Channels:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(lblNoOfChannels, gridBagConstraints);

        lblExpTimes.setText("Exposure Times:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(lblExpTimes, gridBagConstraints);

        lblAlgorithm.setText("Algorithm:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        gridBagConstraints.insets = new java.awt.Insets(2, 2, 2, 2);
        pnlContent.add(lblAlgorithm, gridBagConstraints);

        lblAlgorithm_.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(lblAlgorithm_, gridBagConstraints);

        lblLambda.setText("λ:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
        pnlContent.add(lblLambda, gridBagConstraints);

        txtNoOfPixels.setEditable(false);
        txtNoOfPixels.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.ipadx = 50;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(txtNoOfPixels, gridBagConstraints);

        txtNoOfImages.setEditable(false);
        txtNoOfImages.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.ipadx = 50;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(txtNoOfImages, gridBagConstraints);

        txtNoOfChannels.setEditable(false);
        txtNoOfChannels.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.ipadx = 50;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(txtNoOfChannels, gridBagConstraints);

        txtExpTimes.setEditable(false);
        txtExpTimes.setEnabled(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.ipadx = 200;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(txtExpTimes, gridBagConstraints);

        txtLambda.setText("10");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.ipadx = 50;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
        gridBagConstraints.insets = new java.awt.Insets(1, 1, 1, 1);
        pnlContent.add(txtLambda, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 5);
        add(pnlContent, gridBagConstraints);

        pnlButtons.setLayout(new java.awt.GridBagLayout());

        btnCalc.setLabel("Calculate");
        btnCalc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCalcActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlButtons.add(btnCalc, gridBagConstraints);

        btnSaveBin.setEnabled(false);
        btnSaveBin.setLabel("Save Binary");
        btnSaveBin.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveBinActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlButtons.add(btnSaveBin, gridBagConstraints);

        btnSaveTxt.setEnabled(false);
        btnSaveTxt.setLabel("Save as Text");
        btnSaveTxt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveTxtActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 3;
        gridBagConstraints.gridy = 0;
        pnlButtons.add(btnSaveTxt, gridBagConstraints);

        btnShow.setEnabled(false);
        btnShow.setLabel("Show Curve");
        btnShow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnShowActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlButtons.add(btnShow, gridBagConstraints);

        btnCancel.setLabel("Cancel");
        btnCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCancelActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 4;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlButtons.add(btnCancel, gridBagConstraints);

        btnHelp.setFont(new java.awt.Font("Lucida Grande", 1, 13));
        btnHelp.setLabel("Help");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 5;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
        pnlButtons.add(btnHelp, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
        add(pnlButtons, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_exitForm
        this.dispose();
    }//GEN-LAST:event_exitForm

    private void btnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelActionPerformed
        this.dispose();
    }//GEN-LAST:event_btnCancelActionPerformed

    private void btnCalcActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCalcActionPerformed
        try {
            btnCalc.setEnabled(false);
            btnShow.setEnabled(false);
            btnSaveBin.setEnabled(false);
            btnCancel.setEnabled(false);
            btnHelp.setEnabled(false);
            int type = calculator.getResponseFunctionCalculatorSettings().getType();
            int lambda = Integer.parseInt(txtLambda.getText());
            double[][] g;
            switch (type) {
                case ImagePlus.COLOR_RGB:
                    g = new double[3][];
                    System.out.println("Channel 0:");
                    g[0] = calculator.calcResponse(0, lambda);
                    System.out.println("Channel 1:");
                    g[1] = calculator.calcResponse(1, lambda);
                    System.out.println("Channel 2:");
                    g[2] = calculator.calcResponse(2, lambda);
                    out = new ResponseFunction(g, type, calculator.getW());
                    btnCalc.setEnabled(true);
                    btnShow.setEnabled(true);
                    btnSaveBin.setEnabled(true);
                    btnCancel.setEnabled(true);
                    btnHelp.setEnabled(true);
                    btnSaveTxt.setEnabled(true);
                    break;
                case ImagePlus.GRAY16:
                    g = new double[1][];
                    g[0] = calculator.calcResponse(0, lambda);
                    out = new ResponseFunction(g, type, calculator.getW());
                    btnCalc.setEnabled(true);
                    btnShow.setEnabled(true);
                    btnSaveBin.setEnabled(true);
                    btnCancel.setEnabled(true);
                    btnHelp.setEnabled(true);
                    break;
                default:
                    IJ.error("The image has an unsupported image type!");
                    btnCalc.setEnabled(true);
                    btnShow.setEnabled(false);
                    btnSaveBin.setEnabled(false);
                    btnCancel.setEnabled(true);
                    btnHelp.setEnabled(true);
            }
        } catch (TypeNotSupportedException ex) {
            Logger.getLogger(HDRResponseFunctionCalculatorFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_btnCalcActionPerformed

    private void btnSaveBinActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveBinActionPerformed
        if (getOut() == null) {
            return;
        }
        String fn = calculator.getResponseFunctionCalculatorSettings().getFileName();
        String path = getPath(fn);
        if (path == null) {
            return;
        }
        ObjectOutputStream writer = null;
        try {
            writer = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(path)));
            writer.writeObject(getOut());
        } catch (IOException ex) {
            Logger.getLogger(HDRResponseFunctionCalculatorFrame.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                writer.close();
            } catch (IOException ex) {
                Logger.getLogger(HDRResponseFunctionCalculatorFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
}//GEN-LAST:event_btnSaveBinActionPerformed

    private void btnShowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnShowActionPerformed
        double[] yVal = new double[calculator.getResponseFunctionCalculatorSettings().getLevels()];
        for (int i = 0; i < yVal.length; i++) {
            yVal[i] = i;
        }
        PlotWindow plot;
        switch (out.getType()) {
            case ImagePlus.COLOR_RGB:
                plot = new PlotWindow("Response Function", "x", "y", out.getG()[0], yVal);
                plot.setColor(Color.GREEN);
                plot.addPoints(out.getG()[1], yVal, PlotWindow.LINE);
                plot.setColor(Color.BLUE);
                plot.addPoints(out.getG()[2], yVal, PlotWindow.LINE);
                plot.setColor(Color.RED);
                plot.draw();
                break;
            case ImagePlus.GRAY16:
                plot = new PlotWindow("Response Function", "x", "y", out.getG()[0], yVal);
                plot.draw();
                break;
        }
    }//GEN-LAST:event_btnShowActionPerformed

    private void btnSaveTxtActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveTxtActionPerformed
        
    }//GEN-LAST:event_btnSaveTxtActionPerformed

    private String getPath(String fileName) {
        SaveDialog sd = new SaveDialog("Save as ", fileName, ".rf");
        String outFileName = sd.getFileName();
        if (outFileName == null) {
            return null;
        }
        String directory = sd.getDirectory();
        String path = directory + outFileName;
        return path;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private java.awt.Button btnCalc;
    private java.awt.Button btnCancel;
    private java.awt.Button btnHelp;
    private java.awt.Button btnSaveBin;
    private java.awt.Button btnSaveTxt;
    private java.awt.Button btnShow;
    private java.awt.Label lblAlgorithm;
    private java.awt.Label lblAlgorithm_;
    private java.awt.Label lblExpTimes;
    private java.awt.Label lblLambda;
    private javax.swing.JLabel lblLogo;
    private java.awt.Label lblNoOfChannels;
    private java.awt.Label lblNoOfImages;
    private java.awt.Label lblNoOfPixels;
    private java.awt.Panel pnlButtons;
    private java.awt.Panel pnlContent;
    private java.awt.TextField txtExpTimes;
    private java.awt.TextField txtLambda;
    private java.awt.TextField txtNoOfChannels;
    private java.awt.TextField txtNoOfImages;
    private java.awt.TextField txtNoOfPixels;
    // End of variables declaration//GEN-END:variables

    /**
     * @return the out
     */
    public ResponseFunction getOut() {
        return out;
    }
}
